﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Caching;

namespace PageAdmin.Utils
{

    /// <summary>
    /// 缓存帮助类
    /// </summary>
    public class CacheHelper
    {
        /// <summary>
        /// 获取系统提供的默认缓存
        /// </summary>
        private static ObjectCache DefaultCache
        {
            get
            {
                return MemoryCache.Default;
            }
        }

        /// <summary>
        /// 获取缓存，取出时候内部转换为T类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            if (DefaultCache.Contains(key))
            {
                return (T)DefaultCache[key];
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// 返回一个object类型，可用于保存值类型或普通的
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object Get(string key)
        {
            if (DefaultCache.Contains(key))
            {
                return DefaultCache[key];
            }
            else
            {
                return null;
            } 
        }

        /// <summary>
        /// 添加一个永久缓存，依赖文件
        /// </summary>
        /// <param name="key">缓存保存的键名</param>
        /// <param name="data">缓存数据</param>
        /// <param name="cacheDependencyFile">缓存依赖文件，当文件发生改变时候自动清理</param>
        public static void Add(string key,object data,string cacheDependencyFile)
        {
            if (data == null) return;
            if (!Contains(key))
            {
                var policy = new CacheItemPolicy();//缓存策略
                policy.Priority = CacheItemPriority.NotRemovable;
                cacheDependencyFile = IOHelper.MapPath(cacheDependencyFile);
                List<string> filePaths = new List<string>(){cacheDependencyFile};

                //新建一个文件监视器对象，添加对资源文件的监视
                HostFileChangeMonitor monitor = new HostFileChangeMonitor(filePaths);

                //调用监视器的NotifyOnChanged方法传入发生改变时的回调方法
                monitor.NotifyOnChanged(new OnChangedCallback((o) =>
                {
                    Remove(key);
                }
                 ));
                DefaultCache.Add(new CacheItem(key,data), policy);
            }
        }

        /// <summary>
        /// 添加一个带过期时间的缓存。
        /// </summary>
        /// <param name="key">缓存保存的键名</param>
        /// <param name="data">缓存数据</param>
        /// <param name="cacheMinutes">缓存过期分钟数</param>
        public static void Add(string key, object data,double cacheMinutes= 0)
        {
            if(cacheMinutes<= 0)
            {
                return;
            }
            if (data == null) return;
            if (!Contains(key))
            {
                var policy = new CacheItemPolicy();//缓存策略
                policy.AbsoluteExpiration = DateTime.Now.AddMinutes(cacheMinutes);
                DefaultCache.Add(new CacheItem(key, data), policy);
            }
        }

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <param name="CacheMinutes"></param>
        public static void Update(string key, object data, double CacheMinutes)
        {
            if (data == null) return;
            if (Contains(key))
            {
                var policy = new CacheItemPolicy();//缓存策略
                policy.AbsoluteExpiration = DateTime.Now.AddMinutes(CacheMinutes);
                DefaultCache.Set(new CacheItem(key, data), policy);
            }
        }


        /// <summary>
        /// 更新时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="CacheMinutes"></param>
        public static void Update(string key, double CacheMinutes)
        {
            if (Contains(key))
            {
                object data = Get(key);
                var policy = new CacheItemPolicy();//缓存策略
                policy.AbsoluteExpiration = DateTime.Now.AddMinutes(CacheMinutes);
                DefaultCache.Set(new CacheItem(key, data), policy);
            }
        }

        /// <summary>
        /// 是否存在缓存项
        /// </summary>
        /// <param name="key">换件key</param>
        /// <returns></returns>

        public static bool Contains(string key)
        {
            return DefaultCache.Contains(key);
        }

        /// <summary>
        /// 获取缓存总数
        /// </summary>
        public static int Count { get { return (int)(DefaultCache.GetCount()); } }



        /// <summary>
        /// 移出缓存
        /// </summary>
        /// <param name="key"></param>
        public static void Remove(string key)
        {
            if (Contains(key))
            {
                DefaultCache.Remove(key);
            }
        }

        /// <summary>
        /// 清空所有缓存
        /// </summary>
        /// <param name="regionName"></param>
        public static void RemoveAll(string regionName = null)
        {
            foreach (var item in DefaultCache)
            {
                Remove(item.Key);
            }
        }

        /// <summary>
        /// 列出所有缓存，返回Hashtable类型的IEnumerable,Hash表中包含Id,Name,Value三个字段
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Hashtable> ListCache()
        {
            List<Hashtable> lst = new List<Hashtable>();
            MemoryCache DefaultCache = MemoryCache.Default;
            int i = 0;
            foreach (var item in DefaultCache)
            {
                Hashtable hashTable = new Hashtable();
                hashTable.Add("Id", i);
                hashTable.Add("Name", item.Key);
                hashTable.Add("Value",item.Value.ToString());
                lst.Add(hashTable);
                i++;
            }
            return lst;
        }


        /// <summary>
        /// 获取计算机上最大缓存，单位kb
        /// </summary>
        /// <returns></returns>
        public static long MemoryCacheLimit()
        {
            return MemoryCache.Default.CacheMemoryLimit; ;
        }

        /// <summary>
        /// 获取计算机上最大缓存，单位kb
        /// </summary>
        /// <returns></returns>
        public static long EffectivePrivateBytesLimit()
        {
            return MemoryCache.Default.PhysicalMemoryLimit;
        }
    }
}
